#include <string.h>
#include <iostream>
using std::cout;
using std::endl;
using std::ostream;


class String
{
public:
    String()
    /* : _pstr(nullptr) */
    : _pstr(new char[1]())
    {
        cout << "String()" << endl;
    }

    String(const char *pstr)
    : _pstr(new char[strlen(pstr) + 1]())
    {
        cout << "String(const char *)" << endl;
        strcpy(_pstr, pstr);
    }

    //移动构造
    String(String && rhs)
    : _pstr(rhs._pstr)//浅拷贝
    {
        cout << "String移动构造" << endl;
        rhs._pstr = nullptr;
    }

    //拷贝构造
    String(const String & rhs)
    : _pstr(new char[strlen(rhs._pstr) + 1]())
    {
        cout << "String(const String &)" << endl;
        strcpy(_pstr, rhs._pstr);
    }

    //移动赋值函数
    //s1 = std::move(s1)
    //String && rhs = std::move(s1)
    //
    String & operator=(String && rhs){
        cout << "移动赋值函数" << endl;
        if(this != &rhs){ //自复制判断
            delete [] _pstr;
            _pstr = rhs._pstr;//浅拷贝
            rhs._pstr = nullptr;
        }
        return *this;
    }


    //赋值运算符函数
    String & operator=(const String & rhs)
    {
        cout << "String &operator=(const String &)" << endl;
        if(this != &rhs)
        {
            if(_pstr)
            {
                delete [] _pstr;
            }
            _pstr = new char[strlen(rhs._pstr) + 1]();
            strcpy(_pstr, rhs._pstr);
        }
        return *this;
    }

    size_t length() const
    {
        size_t len = 0;
        if(_pstr)
        {
            len = strlen(_pstr);
        }

        return len;

    }

    const char * c_str() const
    {
        return _pstr;
           
    }


    ~String()
    {
        cout << "~String()" << endl;
        if(_pstr)
        {
            delete [] _pstr;
            _pstr = nullptr;
        }
    }

    void print() const
    {
        if(_pstr)
        {
            cout << "_pstr = " << _pstr << endl;
        }else{
            cout << endl;
        }
    }

    friend
    ostream & operator<<(ostream & os,const String & rhs);
private:
    char * _pstr;
};

ostream & operator<<(ostream & os,const String & rhs){
    os << rhs._pstr;
    return os;
}

//func2函数中执行return语句时
//根据以前的认知，应该调用拷贝构造
//str1对象在func2执行完时就会销毁（将亡对象）
//此时不会调用拷贝构造，而是调用移动构造
//将str1申请的堆空间的管理权移交给一个匿名的对象（func2的返回值）
String func2(){
    String str1("wangdao");
	str1.print();
    return str1;
}

void test3(){
    func2().print();
    /* //&func2(); //error,右值 */
   	/* String && ref = func2(); */
    /* &ref;  //右值引用本身为左值 */
}


//应该调用拷贝构造
String s10("beijing");
String func3(){
    s10.print();
    return s10;//返回值为s10的副本
}

void test4(){
    func3();   //调用拷贝构造函数
}

int main(void){
    test4();
    return 0;
}
